﻿#include "GUIGeometryCylinderDialog.h"
#include "ui_GUIGeometryCylinderDialog.h"

#include "FITK_Interface/FITKInterfaceGeometry/FITKGeoInterfaceFactory.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeomTools.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoModelCylinder.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKGeoCommandList.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsVirtualTopo.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITK_Kernel/FITKCore/FITKActionOperator.h"
#include "FITK_Kernel/FITKCore/FITKDataRepo.h"
#include "PickDataProvider/PickedDataProvider.h"
#include "PickDataProvider/PickedData.h"
#include <QMessageBox>

namespace GUI {
    GUIGeometryCylinderDialog::GUIGeometryCylinderDialog(Interface::FITKAbsGeoCommand* obj,Core::FITKActionOperator* oper, QWidget* parent)
        :Core::FITKDialog(parent), _oper(oper),_obj(obj)
    {
        _ui = new Ui::GUIGeometryCylinderDialog();
        _ui->setupUi(this);
        // 设置对话框关闭时自动删除
        setAttribute(Qt::WA_DeleteOnClose);
        //去掉问号
        Qt::WindowFlags flags = windowFlags();
        flags &= ~Qt::WindowContextHelpButtonHint;
        setWindowFlags(flags);
        if (!_obj)
        {
            _isCreate = true;
            setWindowTitle(tr("Create Cylinder"));
        }
        else
        {
            setWindowTitle(tr("Edit Cylinder"));
        }
        //获取拾取器，绑定拾取结束信号
        GraphData::PickedDataProvider* pickProvider = GraphData::PickedDataProvider::getInstance();        
        //清除拾取对象所有的连接
        if (pickProvider != nullptr)
        {
            connect(pickProvider, &GraphData::PickedDataProvider::sigPickOver, this, &GUIGeometryCylinderDialog::pickFinishedOper);
        }
        this->init();
    }

    GUIGeometryCylinderDialog::~GUIGeometryCylinderDialog()
    {
        if (_ui) {
            delete _ui;
            _ui = nullptr;
        }
        //所有的类在执行完毕后，将清空对3维的操作
        GraphData::PickedDataProvider* pickProvider = GraphData::PickedDataProvider::getInstance();
        if (!pickProvider) return;
        pickProvider->clearPickedData();
        ////拾取对象 关闭
        ////拾取方式 空
        enablePickSig(GUI::GUIPickInfo::PickObjType::POBNone, GUI::GUIPickInfo::PickMethod::PMNone);
    }

    void GUIGeometryCylinderDialog::init()
    {
        //获取几何管理器
        _geometryData = FITKAPP->getGlobalData()->getGeometryData<Interface::FITKGeoCommandList>();
        if (_geometryData == nullptr) return;

        if (_isCreate)
        {
            QString name = _geometryData->checkName(tr("Cylinder-1"));
            _ui->lineEdit_Name->setText(name);
        }
        else
        {
            Interface::FITKAbsGeoModelCylinder* cylinderModel = dynamic_cast<Interface::FITKAbsGeoModelCylinder*>(_obj);
            if (cylinderModel == nullptr) return;
            _ui->lineEdit_Name->setText(cylinderModel->getDataObjectName());
            double location[3] = { 0,0,0 };
            double direction[3] = { 0,0,0 };
            double radius = cylinderModel->getRadius();
            double length = cylinderModel->getLength();
            cylinderModel->getLocation(location);
            cylinderModel->getDirection(direction);
            _ui->lineEdit_X->setText(QString::number(location[0]));
            _ui->lineEdit_Y->setText(QString::number(location[1]));
            _ui->lineEdit_Z->setText(QString::number(location[2]));
            _ui->lineEdit_X_2->setText(QString::number(direction[0]));
            _ui->lineEdit_Y_2->setText(QString::number(direction[1]));
            _ui->lineEdit_Z_2->setText(QString::number(direction[2]));
            _ui->lineEdit_Radius->setText(QString::number(radius));
            _ui->lineEdit_Length->setText(QString::number(length));
        }
    }

    void GUIGeometryCylinderDialog::pickFinishedOper()
    {
        //获取拾取数据
        GraphData::PickedDataProvider* pickProvider = GraphData::PickedDataProvider::getInstance();
        if (!pickProvider) return;

        QList<GraphData::PickedData*> pickList = pickProvider->getPickedList();
        QList<Interface::VirtualShape> virtualShape;
        for (GraphData::PickedData* pickData : pickList) {
            if (pickData == nullptr)continue;
            int cmdID = pickData->getPickedDataObjId();
            QHash<int, int>OtherIDs = pickData->getPickedOtherIDs();//key PickedId  value index
            for (GraphData::PickDataInfo i : pickData->getPickOtherInfos())
            {
                if (OtherIDs.contains(i._id) == true)
                {
                    //添加拾取数据
                    Interface::VirtualShape temp(cmdID, i._id, OtherIDs.value(i._id));
                    virtualShape.push_back(temp);
                }
            }
        }
        if (virtualShape.isEmpty()) return;
        //获取坐标
        Interface::FITKInterfaceGeometryFactory*factory = Interface::FITKInterfaceGeometryFactory::getInstance();
        if (factory == nullptr) return;
        Interface::FITKAbstractGeomToolsCreator*createor = factory->getGeomToolsCreator();
        if (!createor) return;
        Interface::FITKAbstractGeomPointTool *pointTool = createor->createPointTool();
        if (!pointTool) return;
        double PointArray[3];
        pointTool->getXYZ(FITKDATAREPO->getTDataByID<Interface::FITKAbsVirtualTopo>(virtualShape[0].VirtualTopoId), PointArray);
        _ui->lineEdit_X->setText(QString::number(PointArray[0]));
        _ui->lineEdit_Y->setText(QString::number(PointArray[1]));
        _ui->lineEdit_Z->setText(QString::number(PointArray[2]));
    }

    void GUIGeometryCylinderDialog::getDataFormWidget()
    {
        Interface::FITKAbsGeoModelCylinder* cylinderModel = dynamic_cast<Interface::FITKAbsGeoModelCylinder*>(_obj);
        if (cylinderModel == nullptr) return;
        //设置数据
        double point1[3] = { _ui->lineEdit_X->text().toDouble(),
                            _ui->lineEdit_Y->text().toDouble(),
                            _ui->lineEdit_Z->text().toDouble() };
        double direction[3] = { _ui->lineEdit_X_2->text().toDouble(),
                            _ui->lineEdit_Y_2->text().toDouble(),
                            _ui->lineEdit_Z_2->text().toDouble() };
        double radius = _ui->lineEdit_Radius->text().toDouble();
        double length = _ui->lineEdit_Length->text().toDouble();
        cylinderModel->setLocation(point1);
        cylinderModel->setDirection(direction);
        cylinderModel->setRadius(radius);
        cylinderModel->setLength(length);
        _objID = cylinderModel->getDataObjectID();
    }

    bool GUIGeometryCylinderDialog::createObjData()
    {
        if (!_geometryData) return false;
        if (!editObjData())return false;
        _geometryData->appendDataObj(_obj);
        return true;
    }

    bool GUIGeometryCylinderDialog::editObjData()
    {
        if (!_oper || !_obj || !_geometryData) return false;
        //设置名称
        _obj->setDataObjectName(_ui->lineEdit_Name->text());
        //设置界面数据
        this->getDataFormWidget();
        if (_obj->update() == false)
        {
            //创建失败不将该数据append
            QMessageBox::warning(this, "", tr("The geometry could not be created properly").arg(_ui->lineEdit_Name->text()), QMessageBox::Ok);
            return false;
        }
        _oper->setArgs("objID", _objID);
        return true;
    }

    void GUIGeometryCylinderDialog::on_pushButton_OK_clicked()
    {
        if (!_geometryData) return ;
        //获取数据名称
        QString name = _ui->lineEdit_Name->text();
        if (_geometryData->getDataByName(name)) {
            QMessageBox::warning(this, "", tr("\"%1\" already exists and cannot be overwritten.").arg(name), QMessageBox::Ok);
            return ;
        }
        //创建动作
        if (_isCreate)
        {
            Interface::FITKInterfaceGeometryFactory* geoFactory = Interface::FITKInterfaceGeometryFactory::getInstance();
            if (!geoFactory) return;
            _obj = geoFactory->createCommand(Interface::FITKGeoEnum::FITKGeometryComType::FGTCylinder);
            if (!_obj) return;
            if (!this->createObjData())
                return;
            _oper->execProfession();
        }
        //修改动作
        else
        {
            if (!this->editObjData())
                return;
            _oper->execProfession();
        }
        this->accept();
    }

    void GUIGeometryCylinderDialog::on_pushButton_Cancel_clicked()
    {
        //关闭窗口
        _oper->setArgs("objID", -1);
        if (_isCreate) {
            //删除对象
            if (_obj) delete _obj;
            _obj = nullptr;
        }
        this->reject();
    }

    void GUIGeometryCylinderDialog::on_point1_pick_clicked()
    {
        //设置拾取方式
        enablePickSig(GUI::GUIPickInfo::PickObjType::POBGeoVert, GUI::GUIPickInfo::PickMethod::PMSingle);
    }

    void GUIGeometryCylinderDialog::enablePickSig(GUI::GUIPickInfo::PickObjType objType, GUI::GUIPickInfo::PickMethod methodType)
    {
        GUI::GUIPickInfoStru pickInfo = GUI::GUIPickInfo::GetPickInfo();
        pickInfo._pickObjType = GUI::GUIPickInfo::PickObjType(objType);
        pickInfo._pickMethod = GUI::GUIPickInfo::PickMethod(methodType);
        //设置拾取方式
        GUI::GUIPickInfo::SetPickInfo(pickInfo);
    }
}